`include "defines.v"

module WB_Stage (
    input  wire [`BUSLEN-1:0]           regbus_C,
    input  wire [`XLEN-1:0]             regbus_D,
    input  wire [ 2: 0]                 mem_r_ext_type,

    // Regfile W
    input  wire [`REGFILE_ADDR_LEN-1:0] rd_w_addr_i,
    input  wire                         rd_w_en_i,
    input  wire                         rd_w_src,

    output wire [`REGFILE_ADDR_LEN-1:0] rd_w_addr_o,
    output wire                         rd_w_en_o,
    output wire [`XLEN-1:0]             rd_w_data,

    // CSR W
    input  wire                         csr_w_en_i,
    input  wire [`CSR_ADDR_LEN-1:0]     csr_w_addr_i,

    output wire                         csr_w_en_o,
    output wire [`CSR_ADDR_LEN-1:0]     csr_w_addr_o,
    output wire [`MXLEN-1:0]            csr_data
);
    //----------Load Data Extension----------//
    reg  [`XLEN-1:0] regbus_C_ext_data;

    always @(*) begin
        case (mem_r_ext_type)
            `SEXT8  : regbus_C_ext_data = { {56{regbus_C[ 7]}} , regbus_C[ 7: 0] };
            `SEXT16 : regbus_C_ext_data = { {48{regbus_C[15]}} , regbus_C[15: 0] };
            `SEXT32 : regbus_C_ext_data = { {32{regbus_C[31]}} , regbus_C[31: 0] };
            `ZEXT8  : regbus_C_ext_data = { 56'b0 , regbus_C[ 7: 0] };
            `ZEXT16 : regbus_C_ext_data = { 48'b0 , regbus_C[15: 0] };
            `ZEXT32 : regbus_C_ext_data = { 32'b0 , regbus_C[31: 0] };
            default : regbus_C_ext_data = regbus_C;
        endcase
    end

    //----------Regfile/CSR Access----------//
    // Regfile
    assign rd_w_en_o = rd_w_en_i;
    assign rd_w_addr_o    = rd_w_addr_i;
    assign rd_w_data = rd_w_src ?  regbus_C_ext_data  :  regbus_D  ;

    // CSR
    assign csr_w_en_o   = csr_w_en_i;
    assign csr_w_addr_o = csr_w_addr_i;
    assign csr_data     = regbus_C;


endmodule